// 把 packages 目录下的所有包都进行打包
import * as fs from 'fs'
import execa from 'execa'
import * as os from 'os'

const args = process.argv.slice(2)

const isDev = args && args?.[0] === '--watch'
const scopedPath =
  args && args?.[args.length - 1] !== '--watch' && args?.[args.length - 1]

// 'utils', 'models'
const packages = ['core', 'models', 'utils', 'commands'] // 分类 'core', 'models',
const allTargets = scopedPath
  ? [scopedPath]
  : packages
      .map(dir => {
        const childDirs = fs.readdirSync(dir)
        return childDirs.map(child => {
          if (child !== 'cli') {
            return `${dir}/${child}`
          }
          return false
        })
      })
      .flat(Infinity)
      .filter(v => v) // 获取所有的模块
// 借鉴vue3 原理待研究
async function runParallel(maxConcurrency, source, iteratorFn) {
  const ret = []
  const executing = []
  for (const item of source) {
    const p = Promise.resolve().then(() => iteratorFn(item, source))
    ret.push(p)

    if (maxConcurrency <= source.length) {
      const e = p.then(() => executing.splice(executing.indexOf(e), 1))
      executing.push(e)
      if (executing.length >= maxConcurrency) {
        // eslint-disable-next-line no-await-in-loop
        await Promise.race(executing)
      }
    }
  }
  return Promise.all(ret)
}
async function build(target) {
  // rollup -c --environment TARGET:reactivity
  const watchConfig = isDev
    ? ['-c', '-w', '--environment', `TARGET:${target}`]
    : ['-c', '--environment', `TARGET:${target}`]
  await execa('rollup', watchConfig, {
    stdio: 'inherit' // 将子进程打包的信息共享给父进程
  })
}

async function buildAll(targets) {
  await runParallel(os.cpus().length, targets, build)
}

buildAll(allTargets)
